什么是ES6模块?
在ES6中,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。在看到这里的时候感觉很熟悉,这不就是匿名函数自执行,然后一个个匿名函数放在一个个文件中的么,一个模块就是一个放在文件中的匿名自执行函数。两者对比就像下面这样:
// add.js
(function(window){
function add(a, b) {
return a + b;
}
window.add = add // 通过window对象把 add 函数向外开放
})(window)
而使用ES6的模块, 就像下面
// add.js
function add(a, b) {
return a + b;
}
export default add; // 通过export 导出 add方法
当然了,ES6的模块肯定是比匿名函数自执行更加高级的一种封装了。相比于匿名函数,ES6模块具有下面几种特点。
1. ES6默认使用严格模式
, 而不需要使用 "use strict"
2. ES6模块是编译时加载,对代码进行静态分析
3. 对外抛出接口的时候,不会污染全局的对象
4. 能够有效的处理依赖, 而且只会在第一次加载模块时,代码运行一次。后面再次加载,不会重复 运行,会从缓存中读取
......暂时这些,以后待补充
至于为什么时候ES6的模块产生的历史就不讨论,网络上很多。个人感觉明白了它的历史就能更好的明白它的特性。
export 与 import
说到模块,就需要想到两点,一个是模块的对外接口,后面文章中使用导出
来表示,另外一个是引入其他模块的接口,后面文章中使用导入
来表示。
export
命令用于规定模块的导出
,import
命令用于模块的导入
。
重头戏就来了,怎么更好更快的理解模块的导出
与导入
。
当模块引入其他模块的时候,最终是获取其模块导出
的值(基本数据类型或者引用类型)。于是可以这样去理解,当我们引入的模块(文件)已经确定下来了,那么导入
的值也就确定下来。
// add.js
function add(a, b) {
return a + b;
}
export default add
// main.js
import add from './add.js'
add(1,2) // 3
上面导入
的是 add.js 这个模块,其实主要是把add.js 中的 add 函数进行引入。
当需要到导入多个值的时候,可以通过对象来返回多个所需要的值。
// util.js
function add(a, b) {
return a + b;
}
function reduce(a, b) {
return a - b;
}
// 通过对象来返回多个值
export default {add: add, reduce: reduce};
// main.js
import util from './util.js'
console.log(util) // {add: add, reduce: reduce}
到这里,我个人觉得模块的导入
和导出
基本上就已经很好了。因为这样不管是导出还是导入,对接的接口都是简单方便。
当然这只是我觉得。还是上面的例子
// util.js
function add(a, b) {
return a + b;
}
function reduce(a, b) {
return a - b;
}
export default {add: add, reduce: reduce, name: 'util'}
// main.js
import util from './util.js'
util.add(1, 2) // => 3
util.reduce(4, 3) // => 1
util.name // => 'util'
有人说,当导入
的是值是对象的时候,需要多次去使用对象获取属性。 就像上面需要多次使用util去获取属性。ES6中不是有解构赋值么,用来处理对象多次获取属性的问题,那么导入
对象的时候,也可以这样去处理。
于是按照对象的解构赋值,对上面的 main.js 改变。
// main.js
import {add: addFn} from './util.js'
// 这里在`webpack`中编译就已经报错了, ES6模块不支持这种方式
// 使用另外一种解构方式,`导出`模块的属性名与`导入`的变量名一致
// main.js
import { add } from './util.js'
console.log(add) // undefined
// 这里在`webpack`编译中没有报出错误,但是还有警告: "export 'add' was not found
// 于是对 util.js 的`导出`进行改变
//util.js
function add(a, b) {
return a + b;
}
function reduce(a, b) {
return a - b;
}
export {add, reduce, name: 'util'}
// 当修改完util.js 就完成了util.js模块`导出` 与 main.js模块的`导入`对接
模块的导入
与导出
大致可以分为两种模式
1. default 模式
default 模式下,模块中导出
的值可以使用任何类型(不管是基本类型还是引用类型),都可以对外输出。而导入
的此模块也是很简单,提供一个接收的变量就可以(推荐这种模式)
例子如下:
// util.js
function add(a, b) {
return a + b;
}
function reduce(a, b) {
return a - b;
}
const obj = { add, reduce };
export default obj;
// main.js
import util from './util.js';
// util 是可以变换任意名称
console.log(util)// => {add: ƒ, reduce: ƒ}
2. { xxx } 模式
{ xxx } 是不需要在模块导出
的时候使用default的。但是这种方式下,导出的值一定是object的。
而导入
的模块时是需要使用 { xxx }来接收。而且接收的变量名称还必须与导出模块属性名的一样。
例子如下:
// util.js
function add(a, b) {
return a + b;
}
function reduce(a, b) {
return a - b;
}
let obj = { add, reduce };
// export obj; //webpack 编译报错
export { add, reduce };
// 除了这样直接导出对象,还可以像下面这样
export let name = 'util';
// 与 export { name } 效果一样;
深入了解的话,两者还是可以一起合用
function add(a, b) {
return a + b;
}
function reduce(a, b) {
return a - b;
}
export let name = 'util';
export { add, reduce };
// 相当于把这些属性合并在一起
// main.js
import { add, reduce, name } from './util.js'
console.log(add) // add(a, b) { return a + b; }
console.log(name) // util
as 重命名
as 重命名主要是用于 { xxx }模式。因为在导出
的时候,属性名是被确定下来,而在导入
此模块的时候,变量名需要跟此属性名一样才能获取对应的值。而使用 as 不仅能够帮助导出
模块把属性名重命名,也能够帮导入
模块把接收的变量名进行重命名。
例子如下:
// util.js
function add(a, b) {
return a + b;
}
export { add as addFn};
// main.js
import { addFn as add } from './util.js'
console.log(add) // add(a, b) { return a + b; }
上面是个人关于ES6的模块个人理解和学习心得。
另外想要深入了解的可以查看官方文档 http://www.ecma-international...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。